package org.micode.common.ntp;

import lombok.extern.slf4j.Slf4j;
import org.micode.common.helper.PingHelper;

import java.io.IOException;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

/**
 * 获取原子钟的时间，并设置为系统时间
 */
@Slf4j
public class TimeSyncHelper {

    private static Date getNetDate(String hostName) {
        NtpClient ntpClient = new NtpClient();
        try {
           ntpClient.initNtpClient(hostName, 5000);
           return ntpClient.getNtpServerTime();
        } finally {
            ntpClient.stopNtpClient();
        }
    }

    /**
     * 通过调用本地命令date和time修改计算机时间
     *
     * @param date 获取到的最新时钟
     */
    private static void setComputeDate(Date date) {
        Calendar c = Calendar.getInstance(TimeZone.getTimeZone("GMT+8"));
        c.setTime(date);
        int year = c.get(Calendar.YEAR);
        int month = c.get(Calendar.MONTH) + 1;
        int day = c.get(Calendar.DAY_OF_MONTH);
        int hour = c.get(Calendar.HOUR_OF_DAY);
        int minute = c.get(Calendar.MINUTE);
        int second = c.get(Calendar.SECOND);

        c.setTime(new Date());

        int year_c = c.get(Calendar.YEAR);
        int month_c = c.get(Calendar.MONTH) + 1;
        int day_c = c.get(Calendar.DAY_OF_MONTH);
        int hour_c = c.get(Calendar.HOUR_OF_DAY);
        int minute_c = c.get(Calendar.MINUTE);

        String ymd = year + "-" + month + "-" + day;
        String time = hour + ":" + minute + ":" + second;
        try {
            // 日期不一致就修改一下日期
            if (year != year_c || month != month_c || day != day_c) {
                String cmd = getSetDateCmd(ymd);
                runTheCommand(cmd);
            }
            // 时间不一致就修改一下时间
            if (hour != hour_c || minute != minute_c) {
                String cmd = getSetTimeCmd(time);
                runTheCommand(cmd);
            }
        } catch (IOException ex) {
            log.warn("IOException for setComputeDate({})", date, ex);
        } catch (InterruptedException ex) {
            log.warn("InterruptedException for setComputeDate({})", date, ex);
        }
    }

    private static void runTheCommand(String cmd) throws IOException, InterruptedException {
//        log.info(cmd);
        Process process = Runtime.getRuntime().exec(cmd);
        try {
            process.waitFor();
        } finally {
            process.destroy();
        }
    }

    private static String getSetDateCmd(String dateStr) {
        String os = System.getProperty("os.name");
        if (os.contains("Linux")) {
            return "date -s " + dateStr;
        } else {
            return "cmd /c date " + dateStr;
        }
    }

    private static String getSetTimeCmd(String timeStr) {
        String os = System.getProperty("os.name");
        if (os.contains("Linux")) {
            return "date -s " + timeStr;
        } else {
            return "cmd /c time " + timeStr;
        }
    }

    public static void GetWebTime(String hostName) {
        // 检测电脑是否在线
        if (PingHelper.ping(hostName)) {
            // 从网络上获取时间
            Date date = getNetDate(hostName);
            // 修改本机时间
            if (null != date) {
                log.debug("原子钟时间：" + date);
                setComputeDate(date);
            }
        }
    }

    public static void main(String[] args) {
        GetWebTime("ntp.api.bz");
    }

}
